import { defineStore, acceptHMRUpdate } from "pinia";
import { computed, onMounted, ref } from "vue";
import { useTheme } from "vuetify/lib/framework.mjs";
import type { Theme } from "@tauri-apps/api/window";
import { type UnlistenFn, listen } from "@tauri-apps/api/event";
import { FopApi, WindowApi } from "@/lib/api";

const useThemeStore = defineStore("theme", () => {
    // 主题配置
    interface ThemeConfig {
        // 主题名称
        theme: string;
        // 深色模式是否跟随系统
        follow: boolean;
    }

    // 主题管理
    const theme = useTheme();

    // 当前主题名称
    const name = computed(() => theme.global.name.value);

    // 是否为深色主题
    const dark = computed(() => theme.global.current.value.dark);

    // 是否为跟随系统主题
    const follow = ref(true);

    // 主题配置
    const config = computed<ThemeConfig>(() => {
        return {
            theme: name.value,
            follow: follow.value,
        };
    });

    // 可用主题
    const themes: readonly {
        // 主题名称
        name: string;
        // 是否为深色主题
        dark: boolean;
        // 主题描述
        description: string;
    }[] = Object.freeze([
        {
            name: "light",
            dark: false,
            description: "日间",
        },
        {
            name: "dark",
            dark: true,
            description: "夜间",
        },
    ]);

    // 当前主题索引
    const index = ref(0);

    // 取消监听
    const unlistens: UnlistenFn[] = [];

    // 则监听系统日夜间模式
    listen<Theme>("tauri://theme-changed", async (event) => {
        console.log("系统主题切换为", event.payload);
        if (follow.value) {
            // 跟随系统
            if (event.payload === "dark") {
                await setDarkMode(true);
            } else {
                await setDarkMode(false);
            }
        } else {
            // 保持自我
            WindowApi.setWindowTheme(dark.value);
        }
    }).then((unlisten) => {
        unlistens.push(unlisten);
    });

    // 初始化操作
    onMounted(async () => {
        // 默认主题配置
        let config: ThemeConfig = {
            theme: "light",
            follow: true,
        };

        // 尝试从本地读取配置
        try {
            config = await FopApi.readJson<ThemeConfig>("theme");
        } catch (error) {
            console.warn("读取主题配置失败，使用默认为配置", error);
        }

        // 找到对应主题
        // 没找到则使用第一个主题
        let themeIndex = themes.findIndex((theme) => theme.name === config.theme);
        if (themeIndex === -1) {
            themeIndex = 0;
        }

        follow.value = config.follow;

        // 设置主题
        await setTheme(themeIndex);
    });

    /**
     * 保存配置
     */
    async function save() {
        try {
            await FopApi.writeJson("theme", config.value);
        } catch (error) {
            console.error("主题配置保存失败", error);
        }
    }

    /**
     * 设置主题
     * @param newIndex 主题索引
     */
    async function setTheme(newIndex: number) {
        // 获取目标主题
        index.value = newIndex;
        const targetTheme = themes[newIndex];
        if (targetTheme === undefined) {
            return;
        }

        // 记录 dark 状态
        const nowDark = dark.value;
        const targetDark = targetTheme.dark;

        // 相同主题则不处理
        if (theme.global.name.value === targetTheme.name) {
            return;
        }

        // 切换主题
        console.log(`切换主题：${targetTheme.name}`);
        theme.global.name.value = targetTheme.name;

        // dark 模式改变，发送消息到窗口
        if (nowDark !== targetDark) {
            await WindowApi.setWindowTheme(targetDark);
        }

        // 保存主题配置
        await save();
    }

    /**
     * 设置跟随系统主题
     * @param newFollow 是否跟随系统主题
     */
    async function setFollow(newFollow: boolean) {
        if (follow.value === newFollow) {
            return;
        }

        follow.value = newFollow;
        await save();
    }

    /**
     * 设置 日间/夜间 模式
     * @param dark 夜间模式
     */
    async function setDarkMode(dark: boolean) {
        console.log(`切换为 ${dark ? "夜间" : "日间"} 模式`);

        if (dark) {
            // 切换为日间模式
            // 找到第一个为日间模式的配置
            for (let i = 0; i < themes.length; i++) {
                if (themes[i].dark) {
                    await setTheme(i);
                    break;
                }
            }
        } else {
            // 切换为夜间模式
            // 找到第一个为夜间模式的配置
            for (let i = 0; i < themes.length; i++) {
                if (!themes[i].dark) {
                    await setTheme(i);
                    break;
                }
            }
        }
    }

    /**
     * 切换 日间/夜间 模式
     */
    async function toggleDark() {
        await setDarkMode(!dark.value);
    }

    /**
     * 取消监听
     */
    async function unlisten() {
        await Promise.all(unlistens.map((unlisten) => unlisten()));
    }

    return {
        name,
        dark,
        follow: computed(() => follow.value),
        themes: computed(() => themes),
        index: computed(() => index.value),
        setTheme,
        setFollow,
        setDarkMode,
        toggleDark,
        unlisten,
    };
});

if (import.meta.hot) {
    import.meta.hot.accept(acceptHMRUpdate(useThemeStore, import.meta.hot));
}

export default useThemeStore;
